package com.szwistar.common.hxdir;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.stmt.StatementBuilder.StatementType;
import com.j256.ormlite.support.CompiledStatement;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.support.DatabaseConnection;
import com.j256.ormlite.support.DatabaseResults;
import com.szwistar.common.datastruct.Utils;


/**
 * 红外遥控设备
 * @author 张勇
 */
public class IRDevice {
	protected static final Logger LOG = LoggerFactory.getLogger(IRDevice.class);

    private int deviceTypeId;
    private String tableName;
    private String[] keyNames;
    private Class<? extends IRCodeGroup> codeClazz;

    protected IRDevice(int deviceTypeId, String tableName, String[] keyNames, Class<? extends IRCodeGroup> codeClazz) {
        super();
        this.deviceTypeId = deviceTypeId;
        this.tableName = tableName;
        this.keyNames = keyNames;
		this.codeClazz = codeClazz;
    }

    public int getDeviceTypeId() { return deviceTypeId; }
    public String[] getKeyNames() { return keyNames; }

    // 获取本类型设备的品牌名称列表
    public List<String> getBrandNames() {
		try {
	    	String sql = "select distinct brand_cn from " + tableName + " order by pinyin;";
			CompiledStatement stmt = dbconn.getReadOnlyConnection(tableName).compileStatement(
					sql, StatementType.SELECT, null, DatabaseConnection.DEFAULT_RESULT_FLAGS, false);
	    	DatabaseResults rs = stmt.runQuery(null);

	    	List<String> ret = new ArrayList<String>();
	        while(rs.next()) {
	            String brand = rs.getString(0);
	            ret.add(brand);
	        }
	        return ret;
		} catch (Exception e) {
			LOG.error("查询品牌列表失败！{}", e);
	        return null;
		}
    }

    /**
     * 查询码组
     * @param brand 品牌名称
     * @param withoutModel 是否有具体型号
     * @return
     */
    public List<IRCodeGroup> getCodeGroup(String brand, boolean withModel) {
    	if(Utils.isEmpty(brand)) { return null; }
		try {
			@SuppressWarnings("unchecked")
			Dao<IRCodeGroup, Integer> dao = (Dao<IRCodeGroup, Integer>) DaoManager.createDao(dbconn, codeClazz);
			if(withModel) {
				return dao.queryBuilder().where().eq("brand_cn", brand).and().ne("model", "no_model").query();
			} else {
				return dao.queryBuilder().where().eq("brand_cn", brand).and().eq("model", "no_model").query();
			}
		} catch (Exception e) {
			LOG.error("获取遥控码失败！{}", e);
	        return null;
		}
    }

    // 获取本类型设备的指定品牌和型号的码组
    public IRCodeGroup getCodeGroup(String brand, String model) {
    	if(Utils.isEmpty(brand) || Utils.isEmpty(model)) { return null; }
		try {
			@SuppressWarnings("unchecked")
			Dao<IRCodeGroup, Integer> dao = (Dao<IRCodeGroup, Integer>) DaoManager.createDao(dbconn, codeClazz);
			Map<String, Object> cond = new HashMap<String, Object>();
			cond.put("brand_cn", brand);
			cond.put("model", model);
			List<IRCodeGroup> code = dao.queryForFieldValues(cond);
			if(Utils.isEmpty(code)) { return null; }
			return code.get(0);
		} catch (Exception e) {
			LOG.error("获取遥控码失败！{}", e);
	        return null;
		}
    }

    // 获取本类型设备的指定码组
    public IRCodeGroup getCodeGroup(int groupIndex) {
		try {
			@SuppressWarnings("unchecked")
			Dao<IRCodeGroup, Integer> dao = (Dao<IRCodeGroup, Integer>) DaoManager.createDao(dbconn, codeClazz);
			IRCodeGroup code = dao.queryForId(groupIndex);
			return code;
		} catch (Exception e) {
			LOG.error("获取遥控码失败！{}", e);
	        return null;
		}
    }

    protected int getBrand(String brandName) {
        return -1;
    }

    public int getKey(String keyName) {
        String[] keyNames = getKeyNames();
        for (int i = 0; i < keyNames.length; i++) {
            if(keyNames[i].equals(keyName)) { return i; }
        }
        return -1;
    }


	public static final String[] AC_keyNames = {
		/* 0  */ "电源/POWER",
		/* 1  */ "模式/MODE",
		/* 2  */ "风速/SPEED",
		/* 3  */ "扫风1/SWEEP1", // 风向(上下扫风?)
		/* 4  */ "扫风2/SWEEP2", // 自动风向(左右扫风?)
		/* 5  */ "温度+/TEMP+",
		/* 6  */ "温度-/TEMP-",
    };

	public static final String[] DVD_keyNames = {
		/* 0  */ "左/LEFT",
		/* 1  */ "上/UP",
		/* 2  */ "确定/OK",
		/* 3  */ "下/DOWN",
		/* 4  */ "右/RIGHT",
		/* 5  */ "电源/POWER",
		/* 6  */ "静音/MUTE",
		/* 7  */ "快倒/BACKWARD",
		/* 8  */ "播放/PLAY",
		/* 9  */ "快进/FORWARD",
		/* 10 */ "上一个/PREV",
		/* 11 */ "停止/STOP",
		/* 12 */ "下一个/NEXT",
		/* 13 */ "制式/MODEM",
		/* 14 */ "暂停/PAUSE",
		/* 15 */ "标题/TITLE",
		/* 16 */ "开关仓/EJECT",
		/* 17 */ "菜单/MENU",
		/* 18 */ "返回/BACK",
    };

	public static final String[] FAN_keyNames = {
		/* 0  */ "电源/POWER",
		/* 1  */ "风速/SPEED",
		/* 2  */ "摇头/SWEEP",
		/* 3  */ "风类/模式/MODE",
		/* 4  */ "定时/TIMING",
		/* 5  */ "灯光/LAMP",
		/* 6  */ "负离子/ANION",
		/* 7  */ "1/KEY1",
		/* 8  */ "2/KEY2",
		/* 9  */ "3/KEY3",
		/* 10 */ "4/KEY4",
		/* 11 */ "5/KEY5",
		/* 12 */ "6/KEY6",
		/* 13 */ "7/KEY7",
		/* 14 */ "8/KEY8",
		/* 15 */ "9/KEY9",
		/* 16 */ "睡眠/SLEEP",
		/* 17 */ "制冷/COOL",
		/* 18 */ "风量/RATE",
		/* 19 */ "低速/LOW",
		/* 20 */ "中速/MIDDLE",
		/* 21 */ "高速/HIGH",
    };

	public static final String[] IPTV_keyNames = {
		/* 0  */ "电源/POWER",
		/* 1  */ "静音/MUTE",
		/* 2  */ "音量+/VOL+",
		/* 3  */ "音量-/VOL-",
		/* 4  */ "频道+/主页/CH+",
		/* 5  */ "频道-/菜单/CH-",
		/* 6  */ "上/UP",
		/* 7  */ "左/LEFT",
		/* 8  */ "确定/OK",
		/* 9  */ "右/RIGHT",
		/* 10 */ "下/DOWN",
		/* 11 */ "播放/暂停/PLAY/PAUSE",
		/* 12 */ "1/KEY1",
		/* 13 */ "2/KEY2",
		/* 14 */ "3/KEY3",
		/* 15 */ "4/KEY4",
		/* 16 */ "5/KEY5",
		/* 17 */ "6/KEY6",
		/* 18 */ "7/KEY7",
		/* 19 */ "8/KEY8",
		/* 20 */ "9/KEY9",
		/* 21 */ "0/KEY0",
		/* 22 */ "返回/BACK",
    };

	public static final String[] PJT_keyNames = {
		/* 0  */ "开机/ON",
		/* 1  */ "关机/OFF",
		/* 2  */ "电脑/VGA",
		/* 3  */ "视频/VIDEO",
		/* 4  */ "信源/INPUT",
		/* 5  */ "变焦+/ZOOM+",
		/* 6  */ "变焦-/ZOOM-",
		/* 7  */ "画面+/PIC+",
		/* 8  */ "画面-/PIC-",
		/* 9  */ "菜单/MENU",
		/* 10 */ "确定/OK",
		/* 11 */ "上/UP",
		/* 12 */ "左/LEFT",
		/* 13 */ "右/RIGHT",
		/* 14 */ "下/DOWN",
		/* 15 */ "退出/EXIT",
		/* 16 */ "音量+/VOL+",
		/* 17 */ "音量-/VOL-",
		/* 18 */ "静音/MUTE",
		/* 19 */ "自动/AUTO",
		/* 20 */ "暂停/PAUSE",
		/* 21 */ "亮度/BRIGHTNESS",
    };

	public static final String[] TVBOX_keyNames = {
		/* 0  */ "电源/POWER",
		/* 1  */ "1/KEY1",
		/* 2  */ "2/KEY2",
		/* 3  */ "3/KEY3",
		/* 4  */ "4/KEY4",
		/* 5  */ "5/KEY5",
		/* 6  */ "6/KEY6",
		/* 7  */ "7/KEY7",
		/* 8  */ "8/KEY8",
		/* 9  */ "9/KEY9",
		/* 10 */ "导视/GUIDE",
		/* 11 */ "0/KEY0",
		/* 12 */ "返回/BACK",
		/* 13 */ "上/UP",
		/* 14 */ "左/LEFT",
		/* 15 */ "确定/OK",
		/* 16 */ "右/RIGHT",
		/* 17 */ "下/DOWN",
		/* 18 */ "音量+/VOL+",
		/* 19 */ "音量-/VOL-",
		/* 20 */ "频道+/CH+",
		/* 21 */ "频道-/CH-",
		/* 22 */ "菜单/MENU",
    };

	public static final String[] TV_keyNames = {
		/* 0  */ "音量-/VOL-",
		/* 1  */ "频道+/CH+",
		/* 2  */ "菜单/MENU",
		/* 3  */ "频道-/CH-",
		/* 4  */ "音量+/VOL+",
		/* 5  */ "电源/POWER",
		/* 6  */ "静音/MUTE",
		/* 7  */ "1/KEY1",
		/* 8  */ "2/KEY2",
		/* 9  */ "3/KEY3",
		/* 10 */ "4/KEY4",
		/* 11 */ "5/KEY5",
		/* 12 */ "6/KEY6",
		/* 13 */ "7/KEY7",
		/* 14 */ "8/KEY8",
		/* 15 */ "9/KEY9",
		/* 16 */ "-/--/SELECT",
		/* 17 */ "0/KEY0",
		/* 18 */ "信源/INPUT",
		/* 19 */ "返回/BACK",
		/* 20 */ "确定/OK",
		/* 21 */ "上/UP",
		/* 22 */ "左/LEFT",
		/* 23 */ "右/RIGHT",
		/* 24 */ "下/DOWN",
    };

	public static final String[] AUDIO_keyNames = {
		/* 0  */ "左/LEFT",
		/* 1  */ "上/UP",
		/* 2  */ "确定/OK",
		/* 3  */ "下/DOWN",
		/* 4  */ "右/RIGHT",
		/* 5  */ "电源/POWER",
		/* 6  */ "音量加/VOL+",
		/* 7  */ "静音/MUTE",
		/* 8  */ "音量减/VOL-",
		/* 9  */ "快倒/BACKWARD",
		/* 10 */ "播放/PLAY",
		/* 11 */ "快进/FORWARD",
		/* 12 */ "上一个/PREV",
		/* 13 */ "停止/STOP",
		/* 14 */ "下一个/NEXT",
		/* 15 */ "暂停/PAUSE",
		/* 16 */ "菜单/MENU",
		/* 17 */ "返回/BACK",
	};

	public static final String[] SWEEPER_keyNames = {
		/* 0  */ "开机/ON",
		/* 1  */ "关机/OFF",
		/* 2  */ "上/UP"  ,
		/* 3  */ "下/DOWN",
		/* 4  */ "左/LEFT",
		/* 5  */ "右/RIGHT",
		/* 6  */ "确定/OK",
		/* 7  */ "返回/BACK",
		/* 8  */ "模式/MODE",
		/* 9  */ "主页/HOME",
		/* 10 */ "时间/TIME",
		/* 11 */ "区域/AREA",
		/* 12 */ "沿边/EDGE",
		/* 13 */ "局部/PART",
		/* 14 */ "自动/AUTO",
		/* 15 */ "定点/SPOT",
		/* 16 */ "弓形/ARC",
		/* 17 */ "杀菌/STERILIZE",
		/* 18 */ "定时/TIMING",
		/* 19 */ "速度/SPEED",
		/* 20 */ "设置/SETUP",
	};

	public static final String[] AIR_keyNames = {
		/* 0  */ "电源/POWER",
		/* 1  */ "自动/AUTO",
		/* 2  */ "风速/SPEED",
		/* 3  */ "定时/TIMING",
		/* 4  */ "模式/MODE",
		/* 5  */ "负离子/ANION",
		/* 6  */ "舒适/SOFT",
		/* 7  */ "静音/SILENT",
		/* 8  */ "灯光/LIGHT",
		/* 9  */ "强劲/STRONG",
		/* 10 */ "自然/NATURE",
		/* 11 */ "关闭/CLOSE",
		/* 12 */ "睡眠/SLEEP",
		/* 13 */ "智能/SMART",
		/* 14 */ "灯1/LAMP1",
		/* 15 */ "灯2/LAMP2",
		/* 16 */ "灯3/LAMP3",
		/* 17 */ "紫外线/UV",
	};

	public static final String[] WATER_keyNames = {
		/* 0  */ "电源/POWER",
		/* 1  */ "设置/SETUP",
		/* 2  */ "温度+/TEMP+",
		/* 3  */ "温度-/TEMP+",
		/* 4  */ "模式/MODE",
		/* 5  */ "确定/OK",
		/* 6  */ "定时/TIMING",
		/* 7  */ "预约/APPOINTMENT",
		/* 8  */ "时间/TIME",
		/* 9  */ "保温/KEEPWARM",
	};

	public static final String[] LAMP_keyNames = {
		/* 0  */ "开机/ON",
		/* 1  */ "关机/OFF",
		/* 2  */ "亮度+/BRIGHTNESS+",
		/* 3  */ "亮度-/BRIGHTNESS-",
		/* 4  */ "模式/MODE",
		/* 5  */ "设置/SETUP",
		/* 6  */ "定时+/TIMING+",
		/* 7  */ "定时-/TIMING-",
		/* 8  */ "色温+/TEMP+",
		/* 9  */ "色温-/TEMP-",
		/* 10 */ "1/KEY1",
		/* 11 */ "2/KEY2",
		/* 12 */ "3/KEY3",
		/* 13 */ "4/KEY4",
		/* 14 */ "5/KEY5",
		/* 15 */ "6/KEY6",
		/* 16 */ "A/KEYA",
		/* 17 */ "B/KEYB",
		/* 18 */ "C/KEYC",
		/* 19 */ "D/KEYD",
	};

	public static final String[] CAMERA_keyNames = {
		/* 0  */ "拍照/SHUTTER",
	};


    // 支持的设备类型ID(deviceTypeId)
    public static final int DEVICE_PJT     = 0;    // 投影仪
    public static final int DEVICE_FAN     = 1;    // 风扇
    public static final int DEVICE_TVBOX   = 2;    // 机顶盒
    public static final int DEVICE_DVD     = 3;    // DVD
    public static final int DEVICE_TV      = 4;    // 电视机
    public static final int DEVICE_AC      = 5;    // 空调
    public static final int DEVICE_IPTV    = 6;    // IPTV
    public static final int DEVICE_AUDIO   = 7;    // 音响
    public static final int DEVICE_WATER   = 8;    // 热水器
    public static final int DEVICE_AIR     = 9;    // 空气净化器
    public static final int DEVICE_SWEEPER = 10;   // 扫地机器人
    public static final int DEVICE_LAMP    = 11;   // 灯光
    public static final int DEVICE_CAMERA  = 12;   // 照相机/SLR单反相机

    public static final IRDevice PJT     = new IRDevice(DEVICE_PJT,     "pjt_table"    , PJT_keyNames    , IRCodeGroupPJT.class    );
    public static final IRDevice FAN     = new IRDevice(DEVICE_FAN,     "fan_table"    , FAN_keyNames    , IRCodeGroupFAN.class    );
    public static final IRDevice TVBOX   = new IRDevice(DEVICE_TVBOX,   "tvbox_table"  , TVBOX_keyNames  , IRCodeGroupTVBOX.class  );
    public static final IRDevice DVD     = new IRDevice(DEVICE_DVD,     "dvd_table"    , DVD_keyNames    , IRCodeGroupDVD.class    );
    public static final IRDevice TV      = new IRDevice(DEVICE_TV,      "tv_table"     , TV_keyNames     , IRCodeGroupTV.class     );
    public static final IRDevice AC      = new IRDevice(DEVICE_AC,      "arc_table"    , AC_keyNames     , IRCodeGroupAC.class     );
    public static final IRDevice IPTV    = new IRDevice(DEVICE_IPTV,    "iptv_table"   , IPTV_keyNames   , IRCodeGroupIPTV.class   );
    public static final IRDevice AUDIO   = new IRDevice(DEVICE_AUDIO,   "ado_table"    , AUDIO_keyNames  , IRCodeGroupAUDIO.class  );
    public static final IRDevice WATER   = new IRDevice(DEVICE_WATER,   "water_table"  , WATER_keyNames  , IRCodeGroupWATER.class  );
    public static final IRDevice AIR     = new IRDevice(DEVICE_AIR,     "air_table"    , AIR_keyNames    , IRCodeGroupAIR.class    );
    public static final IRDevice SWEEPER = new IRDevice(DEVICE_SWEEPER, "sweeper_table", SWEEPER_keyNames, IRCodeGroupSWEEPER.class);
    public static final IRDevice LAMP    = new IRDevice(DEVICE_LAMP,    "lamp_table"   , LAMP_keyNames   , IRCodeGroupLAMP.class   );
    public static final IRDevice CAMERA  = new IRDevice(DEVICE_CAMERA,  "slr_table"    , CAMERA_keyNames , IRCodeGroupCAMERA.class );

    // 取得设备类型
    public static IRDevice getByType(int type) {
        switch(type) {
        case DEVICE_AC:      return AC;
        case DEVICE_TV:      return TV;
        case DEVICE_IPTV:    return IPTV;
        case DEVICE_TVBOX:     return TVBOX;
        case DEVICE_AUDIO:   return AUDIO;
        case DEVICE_FAN:     return FAN;
        case DEVICE_PJT:     return PJT;
        case DEVICE_DVD:     return DVD;
        case DEVICE_WATER:   return WATER;
        case DEVICE_AIR:     return AIR;
        case DEVICE_SWEEPER: return SWEEPER;
        case DEVICE_CAMERA:  return CAMERA;
        case DEVICE_LAMP:    return LAMP;
        default: return null;
        }
    }

    // 数据库连接
    protected static ConnectionSource dbconn;

	// 打开码库
    public static void open(ConnectionSource dbconn) {
        IRDevice.dbconn = dbconn;
    }

    // 获取指定类型设备的品牌名称列表
    public static List<String> getBrandNames(int typeId) {
    	IRDevice dev = getByType(typeId);
    	if(dev == null) { return null; }
    	return dev.getBrandNames();
    }

	/**
	 * 获取完整的遥控码码组
     * @param typeId 类型ID
     * @param groupIndex 码组号
	 * @return 遥控码字节流
	 */
    public static byte[] getCode(int typeId, int groupIndex) {
    	if(groupIndex < 0) { return null; }
    	IRDevice dev = getByType(typeId); if(dev == null) { return null; }
    	IRCodeGroup group = dev.getCodeGroup(groupIndex); if(group == null) { return null; }
    	return group.code;
    }

	/**
	 * 获取按键对应的遥控码
     * @param typeId 类型ID
     * @param groupIndex 码组号
	 * @param keyName 按键名称
	 * @param extraParams 额外参数（空调需要当前状态做为额外参数）
	 * @return 遥控码字节流
	 */
    public static byte[] getCode(int typeId, int groupIndex, int keyIndex, Object extraParam) {
    	if(groupIndex < 0 || keyIndex < 0) { return null; }
    	IRDevice dev = getByType(typeId); if(dev == null) { return null; }
    	IRCodeGroup group = dev.getCodeGroup(groupIndex); if(group == null) { return null; }
    	return group.getCode(keyIndex, extraParam);
    }
}
